#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
抖音电商(DY) 自动化爬虫
参考JD成熟架构，适配抖音电商特点
支持交互式登录和手动登录两种模式
"""

import os
import sys
import time
import json
import random
import logging
import requests
import re
from datetime import datetime
from typing import Dict, List, Any, Optional, Union

# Selenium相关导入
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import (
    TimeoutException, NoSuchElementException, 
    WebDriverException, ElementNotInteractableException
)

# 添加项目根目录到路径（用于导入webdriver_manager_util）
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if project_root not in sys.path:
    sys.path.insert(0, project_root)

# 导入WebDriver管理器
try:
    from webdriver_manager_util import WebDriverManager
except ImportError:
    print("⚠️ 无法导入webdriver_manager_util，将使用传统方式")
    WebDriverManager = None

# 导入配置
from DY.config import DYConfig

class DYScraper:
    """抖音电商爬虫类"""
    
    def __init__(self, headless: bool = False, debug: bool = False):
        """初始化爬虫"""
        self.headless = headless
        self.debug = debug
        self.driver = None
        self.wait = None
        self.config = DYConfig()
        
        # 设置日志
        self._setup_logging()
        
        # 反检测设置
        self.user_agent = DYConfig.get_random_user_agent()
        
        # 登录状态
        self.is_logged_in = False
        self.login_mode = None  # 'interactive' 或 'manual'
        
        # GUI回调函数
        self.login_confirmation_callback = None
        self.verification_callback = None
        
        self.logger.info(f"DY爬虫初始化完成 - headless: {headless}, debug: {debug}")
    
    def set_login_confirmation_callback(self, callback):
        """设置登录确认回调函数"""
        self.login_confirmation_callback = callback
    
    def set_verification_callback(self, callback):
        """设置验证码处理回调函数"""
        self.verification_callback = callback
    
    def _setup_logging(self):
        """设置日志"""
        self.logger = logging.getLogger('DYScraper')
        self.logger.setLevel(getattr(logging, DYConfig.LOG_LEVEL))
        
        if not self.logger.handlers:
            # 确保输出目录存在
            DYConfig.ensure_output_dir()
            
            # 文件处理器
            file_handler = logging.FileHandler(
                DYConfig.LOG_CONFIG['filename'], 
                encoding='utf-8'
            )
            file_handler.setFormatter(logging.Formatter(DYConfig.LOG_FORMAT))
            
            # 控制台处理器
            console_handler = logging.StreamHandler()
            console_handler.setFormatter(logging.Formatter(DYConfig.LOG_FORMAT))
            
            self.logger.addHandler(file_handler)
            if self.debug:
                self.logger.addHandler(console_handler)
    
    def _init_driver(self):
        """初始化浏览器驱动"""
        try:
            # Chrome选项配置
            chrome_options = Options()
            
            # 基础选项
            for option in DYConfig.get_chrome_options(self.headless):
                chrome_options.add_argument(option)
            
            # 用户代理
            chrome_options.add_argument(f'--user-agent={self.user_agent}')
            
            # 随机窗口大小
            if not self.headless:
                width = random.randint(1200, 1600)
                height = random.randint(800, 1200)
                chrome_options.add_argument(f'--window-size={width},{height}')
            
            # 实验性选项
            chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
            chrome_options.add_experimental_option('useAutomationExtension', False)
            
            # 尝试使用WebDriverManager自动管理ChromeDriver
            if WebDriverManager:
                try:
                    self.logger.info("🔍 使用WebDriverManager自动配置ChromeDriver...")
                    manager = WebDriverManager(logger=self.logger)
                    self.driver = manager.get_chrome_driver(options=chrome_options, headless=self.headless)
                    self.logger.info("✅ ChromeDriver自动配置成功")
                except Exception as e:
                    self.logger.warning(f"⚠️ WebDriverManager初始化失败: {e}")
                    self.logger.info("🔄 回退到传统方式...")
                    self._init_driver_legacy(chrome_options)
            else:
                # 如果没有WebDriverManager，使用传统方式
                self._init_driver_legacy(chrome_options)
            
            # 基础设置
            self.driver.implicitly_wait(DYConfig.WAIT_TIMES['implicit_wait'])
            self.driver.set_page_load_timeout(DYConfig.WAIT_TIMES['page_load_timeout'])
            
            # 执行反检测脚本
            self._execute_anti_detection_script()
            
            # 随机窗口大小（如果非headless）
            if not self.headless:
                width = random.randint(1200, 1600)
                height = random.randint(800, 1200)
                self.driver.set_window_size(width, height)
            
            # 初始化等待对象
            self.wait = WebDriverWait(self.driver, DYConfig.WAIT_TIMES['element_wait'])
            
            self.logger.info("浏览器驱动初始化成功")
            return True
            
        except Exception as e:
            self.logger.error(f"浏览器驱动初始化失败: {e}")
            return False
    
    def _init_driver_legacy(self, chrome_options):
        """传统方式初始化driver（备用方案）"""
        try:
            # 尝试使用本地chromedriver
            if os.path.exists(DYConfig.CHROME_DRIVER_PATH):
                self.logger.info(f"📂 使用本地ChromeDriver: {DYConfig.CHROME_DRIVER_PATH}")
                service = Service(DYConfig.CHROME_DRIVER_PATH)
                self.driver = webdriver.Chrome(service=service, options=chrome_options)
            else:
                self.logger.info("🔄 使用系统PATH中的ChromeDriver")
                self.driver = webdriver.Chrome(options=chrome_options)
                
        except Exception as e:
            self.logger.error(f"❌ 传统方式初始化ChromeDriver失败: {e}")
            raise
    
    def _execute_anti_detection_script(self):
        """执行反检测脚本"""
        try:
            self.driver.execute_script(DYConfig.ANTI_DETECTION_SCRIPT)
            self.logger.debug("反检测脚本执行成功")
        except Exception as e:
            self.logger.warning(f"反检测脚本执行失败: {e}")
    
    def _human_delay(self, min_delay: float = None, max_delay: float = None):
        """人性化延迟"""
        min_delay = min_delay or DYConfig.WAIT_TIMES['human_delay_min']
        max_delay = max_delay or DYConfig.WAIT_TIMES['human_delay_max']
        delay = random.uniform(min_delay, max_delay)
        time.sleep(delay)
    
    def _find_element_by_selectors(self, selectors: List[str], timeout: int = 10) -> Optional[Any]:
        """通过多个选择器查找元素"""
        wait = WebDriverWait(self.driver, timeout)
        
        for selector in selectors:
            try:
                element = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector)))
                return element
            except TimeoutException:
                continue
        
        return None
    
    def _click_element_safely(self, element, method: str = "click"):
        """安全点击元素"""
        try:
            # 滚动到元素可见
            self.driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", element)
            self._human_delay(0.5, 1.0)
            
            # 等待元素可点击
            WebDriverWait(self.driver, 5).until(EC.element_to_be_clickable(element))
            
            if method == "click":
                element.click()
            elif method == "js":
                self.driver.execute_script("arguments[0].click();", element)
            elif method == "action":
                ActionChains(self.driver).move_to_element(element).click().perform()
            
            self._human_delay()
            return True
            
        except Exception as e:
            self.logger.warning(f"点击元素失败 ({method}): {e}")
            return False
    
    def choose_login_mode(self) -> str:
        """选择登录模式"""
        print("\n" + "="*60)
        print("🔐 DY抖音电商登录模式选择")
        print("="*60)
        print("请选择登录方式:")
        print("1. 交互式登录 - 程序自动填写信息，需要手动输入验证码")
        print("2. 手动登录 - 完全手动操作，适合复杂验证场景")
        print("-"*60)
        
        while True:
            choice = input("请输入选择 (1-2): ").strip()
            if choice == "1":
                self.login_mode = "interactive"
                print("✅ 已选择：交互式登录")
                return "interactive"
            elif choice == "2":
                self.login_mode = "manual"
                print("✅ 已选择：手动登录")
                return "manual"
            else:
                print("❌ 无效选择，请输入 1 或 2")
    
    def login_dy(self, mode: str = None) -> bool:
        """DY登录主入口"""
        try:
            # 如果没有指定模式，让用户选择
            if not mode:
                mode = self.choose_login_mode()
            
            self.login_mode = mode
            
            # 导航到登录页面
            print(f"\n🚀 开始DY登录流程 (模式: {mode})...")
            self.driver.get(DYConfig.LOGIN_URL)
            self._human_delay(3, 5)
            
            if mode == "interactive":
                return self._interactive_login()
            elif mode == "manual":
                return self._manual_login()
            else:
                self.logger.error(f"不支持的登录模式: {mode}")
                return False
                
        except Exception as e:
            self.logger.error(f"登录过程出错: {e}")
            return False
    
    def _interactive_login(self) -> bool:
        """交互式登录 - 程序协助用户登录"""
        try:
            print("\n" + "="*60)
            print("🤖 交互式登录模式")
            print("="*60)
            print("程序将协助您完成登录，请按提示操作")
            print("-"*60)
            
            # 等待页面加载
            self._human_delay(2, 3)
            
            # 获取手机号
            phone = input("📱 请输入手机号: ").strip()
            if not phone:
                print("❌ 手机号不能为空")
                return False
            
            # 查找并填写手机号
            print("🔍 正在查找手机号输入框...")
            phone_element = self._find_element_by_selectors(DYConfig.LOGIN_SELECTORS['phone_input'])
            
            if phone_element:
                phone_element.clear()
                # 模拟人类输入
                for char in phone:
                    phone_element.send_keys(char)
                    time.sleep(random.uniform(0.1, 0.3))
                print(f"✅ 已填写手机号: {phone[:3]}****{phone[-4:]}")
            else:
                print("❌ 未找到手机号输入框，请手动填写")
                input("请手动填写手机号后按 Enter 继续...")
            
            self._human_delay(1, 2)
            
            # 点击获取验证码
            print("🔍 正在查找获取验证码按钮...")
            captcha_btn = self._find_element_by_selectors(DYConfig.LOGIN_SELECTORS['get_captcha_btn'])
            
            if captcha_btn:
                if self._click_element_safely(captcha_btn):
                    print("✅ 已点击获取验证码按钮")
                else:
                    print("❌ 点击获取验证码失败，请手动点击")
            else:
                print("❌ 未找到获取验证码按钮，请手动点击")
            
            # 等待用户输入验证码
            print("\n📨 请查收短信验证码...")
            captcha = input("🔢 请输入验证码: ").strip()
            if not captcha:
                print("❌ 验证码不能为空")
                return False
            
            # 查找并填写验证码
            print("🔍 正在查找验证码输入框...")
            captcha_element = self._find_element_by_selectors(DYConfig.LOGIN_SELECTORS['captcha_input'])
            
            if captcha_element:
                captcha_element.clear()
                # 模拟人类输入
                for char in captcha:
                    captcha_element.send_keys(char)
                    time.sleep(random.uniform(0.1, 0.3))
                print("✅ 已填写验证码")
            else:
                print("❌ 未找到验证码输入框，请手动填写")
                input("请手动填写验证码后按 Enter 继续...")
            
            self._human_delay(1, 2)
            
            # 处理用户协议（如果有）
            self._handle_agreement_checkbox()
            
            # 点击登录按钮
            print("🔍 正在查找登录按钮...")
            login_btn = self._find_element_by_selectors(DYConfig.LOGIN_SELECTORS['login_btn'])
            
            if login_btn:
                if self._click_element_safely(login_btn):
                    print("✅ 已点击登录按钮")
                else:
                    print("❌ 点击登录失败，请手动点击")
                    input("请手动点击登录按钮后按 Enter 继续...")
            else:
                print("❌ 未找到登录按钮，请手动点击")
                input("请手动点击登录按钮后按 Enter 继续...")
            
            # 等待登录完成
            return self._wait_for_login_success()
            
        except Exception as e:
            self.logger.error(f"交互式登录失败: {e}")
            return False
    
    def _manual_login(self) -> bool:
        """手动登录 - 用户完全手动操作"""
        try:
            print("\n" + "="*60)
            print("👤 手动登录模式")
            print("="*60)
            print("请在浏览器中手动完成登录操作")
            print("-"*60)
            print("📋 操作步骤:")
            print("   1. 选择手机号登录方式")
            print("   2. 输入手机号")
            print("   3. 点击获取验证码")
            print("   4. 输入收到的验证码")
            print("   5. 勾选用户协议（如果需要）")
            print("   6. 点击登录按钮")
            print("   7. 等待登录成功")
            print("-"*60)
            print("💡 登录成功后通常会跳转到首页，无需额外验证")
            
            # 显示当前页面信息
            print(f"📍 当前页面: {self.driver.current_url}")
            print(f"📄 页面标题: {self.driver.title}")
            
            # 等待用户手动登录
            if hasattr(self, 'login_confirmation_callback') and self.login_confirmation_callback:
                # 使用GUI回调确认
                confirmed = self.login_confirmation_callback("抖音")
            else:
                # 命令行模式
                input("\n✋ 请在浏览器中完成登录操作，然后按 Enter 键继续...")
                confirmed = True
            
            if confirmed:
                # 直接标记为登录成功，无需复杂验证
                print("✅ 手动登录完成，继续后续流程...")
                self.is_logged_in = True
                return True
            else:
                print("❌ 用户取消登录")
                return False
            
        except Exception as e:
            self.logger.error(f"手动登录失败: {e}")
            return False
    
    def _handle_agreement_checkbox(self):
        """处理用户协议复选框"""
        try:
            print("📋 检查用户协议...")
            checkbox = self._find_element_by_selectors(DYConfig.LOGIN_SELECTORS['agreement_checkbox'], timeout=3)
            
            if checkbox:
                if not checkbox.is_selected():
                    if self._click_element_safely(checkbox):
                        print("✅ 已勾选用户协议")
                    else:
                        print("⚠️ 自动勾选协议失败，请手动勾选")
                else:
                    print("✅ 用户协议已勾选")
            else:
                print("ℹ️ 未发现用户协议复选框")
                
        except Exception as e:
            self.logger.warning(f"处理用户协议失败: {e}")
    
    def _wait_for_login_success(self, timeout: int = None) -> bool:
        """等待登录成功（用于交互式登录）"""
        timeout = timeout or DYConfig.WAIT_TIMES['login_wait']
        
        print(f"\n⏳ 等待登录完成 (最长等待 {timeout} 秒)...")
        
        start_time = time.time()
        while time.time() - start_time < timeout:
            try:
                current_url = self.driver.current_url
                
                # 检查URL是否包含登录成功的标识
                for indicator in DYConfig.LOGIN_SUCCESS_INDICATORS:
                    if indicator in current_url:
                        print(f"🎉 登录成功！当前页面: {current_url}")
                        self.is_logged_in = True
                        return True
                
                # 检查页面元素
                success_element = self._find_element_by_selectors(
                    DYConfig.LOGIN_SELECTORS['login_success_indicators'], 
                    timeout=2
                )
                
                if success_element:
                    print(f"🎉 登录成功！检测到用户信息元素")
                    self.is_logged_in = True
                    return True
                
                # 等待一段时间后再检查
                time.sleep(2)
                
            except Exception as e:
                self.logger.debug(f"登录检查出错: {e}")
                time.sleep(2)
        
        print("❌ 登录超时或失败")
        return False
    

    
    def navigate_to_shop(self, shop_url: str) -> bool:
        """导航到商品管理页面"""
        try:
            print(f"\n🔄 导航到商品管理页面: {shop_url}")
            self.driver.get(shop_url)
            self._human_delay(3, 5)
            
            # 检查页面是否加载成功
            current_url = self.driver.current_url
            if "fxg.jinritemai.com" in current_url:
                print(f"✅ 成功导航到: {current_url}")
                return True
            else:
                print(f"⚠️ 页面跳转异常: {current_url}")
                return False
                
        except Exception as e:
            self.logger.error(f"导航失败: {e}")
            return False
    
    def get_product_list(self, max_pages: int = None, max_products_per_page: int = None) -> List[Dict[str, Any]]:
        """获取商品列表"""
        products = []
        
        try:
            print(f"\n📦 开始获取商品列表...")
            
            # 等待页面加载
            self._human_delay(3, 5)
            
            # 查找商品卡片
            product_selectors = [
                'div.style_productNameNew__pTlbD',
                '.style_productNameNew__pTlbD',
                'div[class*="productName"]',
                'div[class*="product-name"]'
            ]
            
            product_elements = []
            for selector in product_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        product_elements = elements
                        print(f"✅ 使用选择器 '{selector}' 找到 {len(elements)} 个商品")
                        break
                except Exception as e:
                    self.logger.debug(f"选择器 '{selector}' 失败: {e}")
            
            if not product_elements:
                print("❌ 未找到商品元素")
                return products
            
            # 限制商品数量
            if max_products_per_page:
                product_elements = product_elements[:max_products_per_page]
            
            print(f"📋 开始处理 {len(product_elements)} 个商品...")
            
            # 提取商品基础信息
            for i, element in enumerate(product_elements):
                try:
                    product_info = self._extract_product_basic_info(element, i)
                    if product_info:
                        products.append(product_info)
                        print(f"✅ 第 {i+1} 个商品信息提取完成: {product_info.get('title', '未知')}")
                    else:
                        print(f"⚠️ 第 {i+1} 个商品信息提取失败")
                except Exception as e:
                    self.logger.error(f"处理第 {i+1} 个商品时出错: {e}")
                    print(f"❌ 第 {i+1} 个商品处理失败: {e}")
            
            print(f"📋 商品列表获取完成，共 {len(products)} 个有效商品")
            return products
            
        except Exception as e:
            self.logger.error(f"获取商品列表失败: {e}")
            print(f"❌ 获取商品列表失败: {e}")
            return products
    
    def _extract_product_basic_info(self, element, index: int) -> Dict[str, Any]:
        """提取商品基础信息"""
        try:
            # 获取商品标题
            title = element.text.strip() if element.text else f"商品 {index + 1}"
            
            # 尝试从父元素获取更多信息
            parent_row = element
            for _ in range(3):  # 向上查找3级父元素
                try:
                    parent_row = parent_row.find_element(By.XPATH, "..")
                    if parent_row.tag_name in ['tr', 'div'] and 'row' in parent_row.get_attribute('class', ''):
                        break
                except:
                    break
            
            # 提取基础信息
            product_info = {
                'index': index,
                'title': title,
                'element': element,  # 保存元素引用用于后续点击
                'status': '未知',
                'price': '未知',
                'stock': '未知',
                'sales': '未知',
                'product_id': '未知'
            }
            
            # 尝试从同行元素中提取其他信息
            try:
                row_text = parent_row.text if parent_row else ""
                if row_text:
                    # 尝试提取商品ID (通常是数字)
                    import re
                    id_match = re.search(r'\b\d{10,}\b', row_text)
                    if id_match:
                        product_info['product_id'] = id_match.group()
                    
                    # 尝试提取状态
                    if '售卖中' in row_text:
                        product_info['status'] = '售卖中'
                    elif '已下架' in row_text:
                        product_info['status'] = '已下架'
                    elif '审核中' in row_text:
                        product_info['status'] = '审核中'
                    
                    # 尝试提取价格
                    price_match = re.search(r'￥?(\d+(?:\.\d+)?)', row_text)
                    if price_match:
                        product_info['price'] = f"￥{price_match.group(1)}"
                        
            except Exception as e:
                self.logger.debug(f"提取行信息失败: {e}")
                
            # 如果从文本中没找到ID，尝试从元素属性中获取
            if product_info['product_id'] == '未知':
                # 尝试从当前元素获取ID
                for attr in ['data-product-id', 'data-goods-id', 'data-id', 'id']:
                    attr_value = element.get_attribute(attr)
                    if attr_value and attr_value.isdigit() and len(attr_value) >= 10:
                        product_info['product_id'] = attr_value
                        break
                
                # 尝试从父元素获取ID
                if product_info['product_id'] == '未知':
                    try:
                        parent = element.find_element(By.XPATH, "..")
                        for attr in ['data-product-id', 'data-goods-id', 'data-id']:
                            attr_value = parent.get_attribute(attr)
                            if attr_value and attr_value.isdigit() and len(attr_value) >= 10:
                                product_info['product_id'] = attr_value
                                break
                    except:
                        pass
                
                # 尝试从HTML内容中查找ID模式
                if product_info['product_id'] == '未知':
                    try:
                        parent_html = parent_row.get_attribute('innerHTML') if parent_row else ""
                        # 查找常见的ID模式
                        id_patterns = [
                            r'product[_-]?id["\']?\s*[:=]\s*["\']?(\d{10,})',
                            r'goods[_-]?id["\']?\s*[:=]\s*["\']?(\d{10,})',
                            r'id["\']?\s*[:=]\s*["\']?(\d{10,})',
                            r'(\d{13,19})',  # 长数字ID
                        ]
                        
                        for pattern in id_patterns:
                            match = re.search(pattern, parent_html, re.IGNORECASE)
                            if match:
                                product_info['product_id'] = match.group(1)
                                self.logger.debug(f"从HTML模式中提取到ID: {match.group(1)}")
                                break
                    except:
                        pass
            
            return product_info
            
        except Exception as e:
            self.logger.error(f"提取商品基础信息失败: {e}")
            return None
    
    def _extract_id_from_href(self, element) -> str:
        """从href属性中提取商品ID"""
        try:
            # 查找包含href的链接元素
            link_element = element.find_element(By.TAG_NAME, 'a')
            href = link_element.get_attribute('href')
            if href:
                # 从URL中提取ID
                import re
                id_match = re.search(r'id[=:](\d+)', href)
                if id_match:
                    return id_match.group(1)
        except:
            pass
        return ""
    
    def _extract_id_from_parent(self, element) -> str:
        """从父元素的属性中提取商品ID"""
        try:
            parent = element.find_element(By.XPATH, "..")
            for attr in ['data-product-id', 'data-goods-id', 'data-id']:
                value = parent.get_attribute(attr)
                if value:
                    return value
        except:
            pass
        return ""
    
    def _extract_id_from_onclick(self, element) -> str:
        """从onclick属性中提取商品ID"""
        try:
            onclick = element.get_attribute('onclick')
            if onclick:
                import re
                id_match = re.search(r'\b(\d{10,})\b', onclick)
                if id_match:
                    return id_match.group(1)
        except:
            pass
        return ""
    
    def _extract_id_from_context(self, element) -> str:
        """从上下文环境中提取商品ID"""
        try:
            # 查找同级或父级元素中的ID信息
            parent = element.find_element(By.XPATH, "..")
            parent_text = parent.get_attribute('innerHTML')
            if parent_text:
                import re
                # 查找长数字ID
                id_match = re.search(r'\b(\d{10,})\b', parent_text)
                if id_match:
                    return id_match.group(1)
        except:
            pass
        return ""
    
    def get_product_details(self, products: List[Dict[str, Any]], max_products: int = None) -> List[Dict[str, Any]]:
        """获取商品详情"""
        detailed_products = []
        
        try:
            if max_products:
                products = products[:max_products]
            
            print(f"\n🔍 开始获取商品详情 (共 {len(products)} 个)...")
            
            for i, product in enumerate(products):
                try:
                    print(f"\n📋 正在获取第 {i+1}/{len(products)} 个商品详情...")
                    
                    # 点击商品标题打开详情
                    if self._click_product_title(product):
                        # 获取iframe详情数据
                        detail_data = self._get_iframe_detail_data()
                        if detail_data:
                            # 合并基础信息和详情数据
                            detailed_product = {**product, **detail_data}
                            detailed_products.append(detailed_product)
                            print(f"✅ 第 {i+1} 个商品详情获取完成")
                        else:
                            print(f"⚠️ 第 {i+1} 个商品详情获取失败，使用基础信息")
                            detailed_products.append(product)
                        
                        # 关闭详情页
                        self._close_product_detail()
                    else:
                        print(f"❌ 第 {i+1} 个商品无法点击，使用基础信息")
                        detailed_products.append(product)
                    
                    # 随机延迟（优化性能）
                    self._human_delay(1, 2)
                    
                except Exception as e:
                    self.logger.error(f"处理第 {i+1} 个商品详情时出错: {e}")
                    print(f"❌ 第 {i+1} 个商品详情处理失败: {e}")
                    # 添加基础信息
                    detailed_products.append(product)
            
            print(f"\n🎉 商品详情获取完成，共 {len(detailed_products)} 个商品")
            return detailed_products
            
        except Exception as e:
            self.logger.error(f"获取商品详情失败: {e}")
            print(f"❌ 获取商品详情失败: {e}")
            return detailed_products
    
    def _click_product_title(self, product: Dict[str, Any]) -> bool:
        """点击商品标题打开详情"""
        try:
            element = product.get('element')
            if not element:
                return False
            
            # 滚动到元素可见
            self.driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", element)
            self._human_delay(1, 2)
            
            # 尝试多种点击方式
            click_methods = [
                ('direct', lambda: element.click()),
                ('js', lambda: self.driver.execute_script("arguments[0].click();", element)),
                ('action', lambda: ActionChains(self.driver).move_to_element(element).click().perform())
            ]
            
            for method_name, method in click_methods:
                try:
                    method()
                    self.logger.info(f"✅ 使用 {method_name} 方法成功点击商品标题")
                    
                    # 短暂等待详情drawer加载
                    print("🔍 等待详情页面加载...")
                    self._human_delay(0.5, 1)
                    
                    print("🔍 检查页面状态...")
                    
                    # 等待验证码可能的异步加载
                    self._human_delay(1, 2)
                    
                    print("🔍 检查主页面是否有验证码...")
                    # 简化验证码检测 - 直接检查关键文字和iframe可用性
                    if self._simple_verification_check():
                        print("🔍 检测到验证码或页面异常，需要手动处理")
                        if self._handle_verification_pause(product):
                            print("✅ 验证处理完成，继续获取详情")
                            return True
                        else:
                            print("❌ 验证处理失败或用户选择跳过")
                            return False
                    else:
                        print("✅ 页面状态正常，继续获取详情")
                    
                    return True
                    
                except Exception as e:
                    self.logger.debug(f"{method_name} 点击失败: {e}")
                    continue
            
            return False
            
        except Exception as e:
            self.logger.error(f"点击商品标题失败: {e}")
            return False
    
    def _get_iframe_detail_data(self) -> Dict[str, Any]:
        """获取iframe中的详情数据"""
        try:
            # 查找iframe
            iframe_selectors = [
                'iframe[title="预览"]',
                'iframe[src*="haohuo.jinritemai.com"]',
                'iframe[src*="detail"]',
                '.style_iframeContainer__z6W9Q iframe',
                'iframe'
            ]
            
            iframe = None
            for selector in iframe_selectors:
                try:
                    iframe = self.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, selector)))
                    if iframe:
                        self.logger.info(f"✅ 找到iframe: {selector}")
                        break
                except:
                    continue
            
            if not iframe:
                print("❌ 未找到商品详情iframe")
                return {}
            
            # 获取iframe的src URL
            iframe_src = iframe.get_attribute('src')
            if not iframe_src:
                print("❌ iframe没有src属性")
                return {}
            
            print(f"🔗 iframe URL: {iframe_src}")
            
            # 请求iframe内容
            detail_data = self._fetch_iframe_content(iframe_src)
            # 添加iframe URL作为product_url并提取product_id
            if detail_data:
                detail_data['product_url'] = iframe_src
            else:
                detail_data = {'product_url': iframe_src}
            
            # 从iframe URL中提取product_id
            import re
            id_match = re.search(r'id=(\d+)', iframe_src)
            if id_match:
                product_id = id_match.group(1)
                detail_data['product_id'] = product_id
                print(f"✅ 从iframe URL提取product_id: {product_id}")
            else:
                print("⚠️ 无法从iframe URL提取product_id")
            return detail_data
            
        except Exception as e:
            self.logger.error(f"获取iframe详情数据失败: {e}")
            return {}
    
    def _fetch_iframe_content(self, iframe_url: str) -> Dict[str, Any]:
        """使用Selenium获取iframe内容并解析"""
        try:
            print(f"🔗 使用Selenium访问iframe: {iframe_url}")
            
            # 保存当前窗口句柄
            main_window = self.driver.current_window_handle
            
            # 打开新标签页访问iframe URL
            self.driver.execute_script("window.open();")
            self.driver.switch_to.window(self.driver.window_handles[-1])
            
            # 导航到iframe URL
            self.driver.get(iframe_url)
            
            # 快速验证页面基本可用（超短等待）
            try:
                from selenium.webdriver.support.ui import WebDriverWait
                from selenium.webdriver.support import expected_conditions as EC
                from selenium.webdriver.common.by import By
                
                # 只等待body元素存在，最多等待1秒
                WebDriverWait(self.driver, 1).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, 'body'))
                )
                print("✅ 页面基础加载完成")
            except Exception as e:
                print(f"⚠️ 页面加载检查超时，继续处理")
            
            # 两阶段验证码检测：立即检测 + 延迟检测
            print("🔍 第一次验证码检测（立即）...")
            if self._quick_verification_check():
                print("⚠️ iframe页面出现验证码，需要手动处理")
                if not self._handle_verification_pause({'title': 'iframe详情页'}):
                    # 用户选择跳过，关闭标签页返回
                    self.driver.close()
                    self.driver.switch_to.window(main_window)
                    return {}
            else:
                print("✅ 第一次检测：未发现验证码")
                
                # 等待验证码可能的异步加载
                print("🔍 等待验证码异步加载...")
                self._human_delay(3, 5)  # 给验证码充足的加载时间
                
                print("🔍 第二次验证码检测（延迟）...")
                if self._quick_verification_check():
                    print("⚠️ iframe页面出现验证码（延迟检测），需要手动处理")
                    if not self._handle_verification_pause({'title': 'iframe详情页'}):
                        # 用户选择跳过，关闭标签页返回
                        self.driver.close()
                        self.driver.switch_to.window(main_window)
                        return {}
                else:
                    print("✅ 第二次检测：确认无验证码，继续处理")
            
            # 快速获取页面信息，设置短超时
            try:
                self.driver.set_page_load_timeout(3)  # 设置3秒超时
                page_title = self.driver.title or "无标题"
                page_url = self.driver.current_url
                print(f"🔍 iframe页面标题: {page_title}")
                print(f"🔍 iframe页面URL: {page_url}")
            except Exception as e:
                print(f"🔍 iframe页面信息获取超时，继续处理")
            finally:
                # 恢复默认超时设置
                self.driver.set_page_load_timeout(30)
            
            # 前面已经充分检测验证码，这里只需短暂等待内容加载
            print("🔍 等待页面内容完全加载...")
            self._human_delay(0.5, 1)  # 很短的等待，因为前面已经等待过了
            
            # 获取页面HTML内容
            print("📄 开始获取页面源码...")
            page_source = self.driver.page_source
            print(f"📄 页面源码获取完成，长度: {len(page_source)} 字符")
            
            # 检查页面源码中是否包含验证码相关内容
            print(f"📄 页面内容长度: {len(page_source)} 字符")
            
            # 页面内容获取后，如果内容异常少，可能需要再次检查验证码
            # （但通常前面已经检测过了）
            
            # 检查页面内容是否太少（仅作提示，不触发验证码检测）
            if len(page_source) < 10000:  # 正常详情页应该有更多内容
                print("⚠️ 页面内容异常少，可能存在加载问题")
            
            # 使用BeautifulSoup解析
            print("🔍 开始解析HTML内容...")
            from bs4 import BeautifulSoup
            soup = BeautifulSoup(page_source, 'html.parser')
            
            # 调试：检查iframe内容的关键部分
            print("🔍 iframe内容调试:")
            print(f"  - HTML标题: {soup.title.text if soup.title else '无标题'}")
            print(f"  - body子元素数量: {len(soup.find('body').find_all()) if soup.find('body') else 0}")
            
            # 检查是否有典型的商品详情页内容
            product_info_sections = soup.find_all(['div', 'section'], class_=lambda x: x and any(
                keyword in x.lower() for keyword in ['product', 'goods', 'detail', 'info', 'param', '商品', '详情', '参数']
            )) if soup else []
            print(f"  - 商品信息区域数量: {len(product_info_sections)}")
            
            # 检查是否有图片
            images = soup.find_all('img') if soup else []
            print(f"  - 图片数量: {len(images)}")
            if images:
                print(f"  - 第一张图片src: {images[0].get('src', '无src')[:100]}")
            
            # 检查文本内容长度和类型
            text_content = soup.get_text() if soup else ""
            print(f"  - 文本内容长度: {len(text_content)} 字符")
            if len(text_content) > 0:
                print(f"  - 文本内容示例: {text_content[:200].strip()}...")
            
            # 解析iframe内容
            detail_data = self._parse_iframe_html(soup)
            print("✅ HTML内容解析完成")
            
            # 关闭当前标签页并切换回主窗口
            self.driver.close()
            self.driver.switch_to.window(main_window)
            
            print(f"✅ iframe内容获取完成")
            return detail_data
            
        except Exception as e:
            self.logger.error(f"获取iframe内容失败: {e}")
            # 确保切换回主窗口
            try:
                if len(self.driver.window_handles) > 1:
                    self.driver.close()
                    self.driver.switch_to.window(self.driver.window_handles[0])
            except:
                pass
            return {}
    
    def _parse_iframe_html(self, soup) -> Dict[str, Any]:
        """解析iframe HTML内容"""
        try:
            detail_data = {}
            
            # 提取商品图片
            print("🔍 开始提取商品图片...")
            image_selectors = [
                '.head-figure__media-view__content',
                '.gallery-component__preview',
                '.product-image img',
                '.detail-image img',
                'img[src*="ecombdimg.com"]',
                'img[src*="item.ecombdimg.com"]'
            ]
            
            for selector in image_selectors:
                try:
                    elements = soup.select(selector)
                    for element in elements:
                        # 从style background-image中提取
                        if element.get('style'):
                            style = element.get('style')
                            import re
                            bg_match = re.search(r'background-image:\s*url\(["\']?([^"\']+)["\']?\)', style)
                            if bg_match:
                                img_url = bg_match.group(1)
                                if 'ecombdimg.com' in img_url:
                                    detail_data['product_image'] = img_url
                                    print(f"✅ 从background-image提取图片: {img_url}")
                                    break
                        
                        # 从src属性中提取
                        if element.name == 'img' and element.get('src'):
                            img_url = element.get('src')
                            if 'ecombdimg.com' in img_url:
                                detail_data['product_image'] = img_url
                                print(f"✅ 从src属性提取图片: {img_url}")
                                break
                    
                    if 'product_image' in detail_data:
                        break
                except Exception as e:
                    continue
            
            if 'product_image' not in detail_data:
                print("⚠️ 未找到商品图片")
            
            # 提取价格
            price_selectors = [
                '.price-line__price-container__price__amount',
                '.price-line__price-container__price',
                '[class*="price"]'
            ]
            
            for selector in price_selectors:
                try:
                    price_element = soup.select_one(selector)
                    if price_element:
                        price_text = price_element.get_text(strip=True)
                        if price_text and price_text.replace('.', '').isdigit():
                            detail_data['detail_price'] = f"￥{price_text}"
                            break
                except:
                    continue
            
            # 提取标题
            title_selectors = [
                '.title-info__text',
                '.title-info',
                '[class*="title"]'
            ]
            
            for selector in title_selectors:
                try:
                    title_element = soup.select_one(selector)
                    if title_element:
                        detail_data['detail_title'] = title_element.get_text(strip=True)
                        break
                except:
                    continue
            
            # 提取保障信息
            safety_info = []
            try:
                safety_elements = soup.select('.safety-wrapper__content__item__main__text')
                for element in safety_elements:
                    text = element.get_text(strip=True)
                    if text and text != '·':
                        safety_info.append(text)
            except:
                pass
            
            if safety_info:
                detail_data['safety_info'] = '; '.join(safety_info)
            
            # 提取物流信息
            try:
                logistics_element = soup.select_one('.logistics-wrapper__content__item__wrap-main__text')
                if logistics_element:
                    detail_data['logistics_info'] = logistics_element.get_text(strip=True)
            except:
                pass
            
            # 提取产品参数
            params = {}
            try:
                param_rows = soup.select('.product-param__params__content__item__content__row')
                for row in param_rows:
                    try:
                        key_element = row.select_one('.product-param__params__content__item__content__row__key')
                        value_element = row.select_one('.product-param__params__content__item__content__row__value__desc__text')
                        
                        if key_element and value_element:
                            key = key_element.get_text(strip=True)
                            value = value_element.get_text(strip=True)
                            if key and value:
                                params[key] = value
                    except:
                        continue
            except:
                pass
            
            if params:
                detail_data['product_params'] = params
            
            # 提取店铺信息
            try:
                shop_name_element = soup.select_one('.shop-component__shop-content__basic-info__title-area__name')
                if shop_name_element:
                    detail_data['shop_name'] = shop_name_element.get_text(strip=True)
                
                shop_score_element = soup.select_one('.shop-component__shop-content__basic-info__rate-info__no-score')
                if shop_score_element:
                    detail_data['shop_score'] = shop_score_element.get_text(strip=True)
            except:
                pass
            
            return detail_data
            
        except Exception as e:
            self.logger.error(f"解析iframe HTML失败: {e}")
            return {}
    
    def _quick_verification_check(self) -> bool:
        """快速验证码检测 - 立即检查，不等待"""
        try:
            # 最常见的DY验证码选择器，快速检测
            quick_selectors = [
                '[class*="slider"]',
                '.captcha_verify_container',
                '.secsdk-captcha-wrapper',
                '[class*="captcha"]'
            ]
            
            for selector in quick_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        for element in elements:
                            if element.is_displayed():
                                print(f"⚡ 快速检测到验证码: {selector}")
                                return True
                except:
                    continue
            
            return False
            
        except Exception as e:
            return False
    
    def _simple_verification_check(self) -> bool:
        """精准验证码检测 - 只检测核心验证码文字"""
        try:
            # 最快的方法：直接检查页面源码中是否包含验证码关键文字
            page_source = self.driver.page_source
            print(f"🔍 页面源码长度: {len(page_source)} 字符")
            
            # 只检查最核心的验证码文字（避免误判）
            verification_keywords = [
                '请完成下列验证后继续',
                '按住左边按钮拖动完成上方拼图'
            ]
            
            found_keywords = []
            for keyword in verification_keywords:
                if keyword in page_source:
                    found_keywords.append(keyword)
                    print(f"⚡ 发现验证码关键字: {keyword}")
            
            if found_keywords:
                print(f"🔴 检测结果: 发现 {len(found_keywords)} 个验证码关键字")
                return True
            else:
                print(f"🟢 检测结果: 未发现验证码关键字")
                return False
            
        except Exception as e:
            print(f"🔍 验证码检测异常: {e}")
            return False
    
    def _check_for_verification_issues(self) -> bool:
        """检查是否出现验证码或页面异常"""
        try:
            # 专门针对DY的验证码检测
            dy_verification_selectors = [
                # DY滑块验证码
                '.captcha_verify_container',
                '.secsdk-captcha-wrapper',
                '.captcha-wrapper',
                '[class*="captcha"]',
                '[class*="verify"]',
                '[class*="slider"]',
                # 通用滑块验证码
                '.slide-verify',
                '.slider-verify', 
                '.geetest_slider',
                # 点击验证码
                '[class*="click-verify"]',
                '[class*="puzzle"]',
                # 图形验证码
                '[class*="image-captcha"]',
                '[class*="graphic-verify"]',
                # 通用验证相关
                '.verify-container',
                '.captcha-container',
                '.security-verify',
                # iframe中的验证码
                'iframe[src*="captcha"]',
                'iframe[src*="verify"]'
            ]
            
            # 快速获取页面信息
            try:
                current_url = self.driver.current_url
                current_title = self.driver.title or "无标题"
                print(f"🔍 当前页面URL: {current_url}")
                print(f"🔍 当前页面标题: {current_title}")
            except Exception as e:
                print(f"🔍 页面信息获取失败，继续验证码检测")
            
            # 检查验证码相关元素
            verification_selectors = dy_verification_selectors
            
            found_elements = []
            for selector in verification_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        for element in elements:
                            if element.is_displayed():
                                found_elements.append(selector)
                                self.logger.info(f"🔍 检测到验证码元素: {selector}")
                                print(f"✅ 发现验证码: {selector}")
                                return True
                except Exception as e:
                    continue
            
            print(f"🔍 未发现验证码元素，检查了 {len(verification_selectors)} 个选择器")
            
            # 检查页面标题和URL中的验证相关关键词
            current_url = self.driver.current_url.lower()
            current_title = self.driver.title.lower()
            
            verification_keywords = [
                'verify', 'captcha', '验证', '人机验证', 'security', 
                'challenge', 'robot', 'slider', '滑动'
            ]
            
            for keyword in verification_keywords:
                if keyword in current_url or keyword in current_title:
                    self.logger.info(f"🔍 页面标题或URL包含验证关键词: {keyword}")
                    return True
            
            # 快速检查页面内容中的验证相关文本（跳过耗时的全文检索）
            try:
                # 使用更高效的方式检查验证文本 - 只检查关键区域
                verification_areas = [
                    # 检查页面中常见的验证提示区域
                    '.captcha-tips',
                    '.verify-tips', 
                    '.security-tips',
                    '[class*="tips"]',
                    '[class*="message"]',
                    '.ant-message'
                ]
                
                verification_texts = [
                    '请完成验证', '滑动验证', '点击验证', '图形验证码', 
                    '人机验证', '安全验证', '验证码'
                ]
                
                # 只检查特定区域的文本，避免全页面文本获取
                for area_selector in verification_areas:
                    try:
                        elements = self.driver.find_elements(By.CSS_SELECTOR, area_selector)
                        for element in elements[:3]:  # 最多检查3个元素
                            if element.is_displayed():
                                element_text = element.text.lower()
                                for text in verification_texts:
                                    if text in element_text:
                                        self.logger.info(f"🔍 验证区域包含验证文本: {text}")
                                        return True
                    except:
                        continue
                        
                # 如果上述快速检查没有发现，进行有限的页面内容检查
                print("🔍 进行快速页面内容检查...")
                try:
                    # 使用JavaScript快速获取页面可见文本的一小部分
                    page_sample = self.driver.execute_script("""
                        var texts = [];
                        var elements = document.querySelectorAll('div, span, p');
                        for(var i = 0; i < Math.min(elements.length, 50); i++) {
                            var text = elements[i].innerText;
                            if(text && text.length < 100) {
                                texts.push(text.toLowerCase());
                            }
                        }
                        return texts.join(' ');
                    """)
                    
                    for text in verification_texts:
                        if text in page_sample:
                            self.logger.info(f"🔍 页面内容包含验证文本: {text}")
                            return True
                except:
                    pass
                    
            except Exception as e:
                # 如果获取页面文本失败，不影响验证码检测流程
                print(f"🔍 页面内容检查跳过: {str(e)[:50]}")
                pass
            
            return False
            
        except Exception as e:
            self.logger.debug(f"检查验证码时出错: {e}")
            return False
    
    def _handle_verification_pause(self, product: Dict[str, Any]) -> bool:
        """处理验证码暂停"""
        try:
            product_name = product.get('title', '未知商品')
            
            print("\n" + "="*60)
            print("⚠️  验证码检测 - 需要手动处理")
            print("="*60)
            print(f"📦 当前商品: {product_name}")
            print(f"📍 当前页面: {self.driver.current_url}")
            print(f"📄 页面标题: {self.driver.title}")
            print("-"*60)
            print("🔧 请在浏览器中手动处理:")
            print("   1. 完成滑动验证码")
            print("   2. 完成点击验证码")
            print("   3. 完成图形验证码")
            print("   4. 等待页面正常加载")
            print("-"*60)
            print("💡 处理完成后选择:")
            print("   c/C - 继续获取当前商品详情")
            print("   s/S - 跳过当前商品")
            print("   q/Q - 退出整个程序")
            print("="*60)
            
            # 使用GUI回调或命令行交互
            if hasattr(self, 'verification_callback') and self.verification_callback:
                # 使用GUI回调
                action = self.verification_callback("抖音", "iframe详情页")
                if action == 'continue':
                    print("✅ 继续获取商品详情...")
                    self._human_delay(0.5, 1)
                    return True
                elif action == 'skip':
                    print("⏸️  跳过当前商品")
                    return False
                elif action == 'quit':
                    print("🛑 用户选择退出程序")
                    raise KeyboardInterrupt("用户手动退出")
                else:
                    print("❌ 用户取消操作")
                    return False
            else:
                # 命令行交互模式
                while True:
                    user_choice = input("请选择操作 (c=继续/s=跳过/q=退出): ").strip().lower()
                    
                    if user_choice in ['c', 'continue', '继续']:
                        print("✅ 继续获取商品详情...")
                        self._human_delay(0.5, 1)  # 减少等待时间
                        return True
                    elif user_choice in ['s', 'skip', '跳过']:
                        print("⏸️  跳过当前商品")
                        return False
                    elif user_choice in ['q', 'quit', '退出']:
                        print("🛑 用户选择退出程序")
                        raise KeyboardInterrupt("用户手动退出")
                    else:
                        print("❌ 无效选择，请输入 c(继续)/s(跳过)/q(退出)")
            
        except KeyboardInterrupt:
            raise
        except Exception as e:
            self.logger.error(f"处理验证码暂停时出错: {e}")
            return False
    
    def _close_product_detail(self):
        """关闭商品详情页"""
        try:
            # 查找关闭按钮
            close_selectors = [
                '.ecom-g-drawer-header-close',
                '.ecom-g-drawer .ecom-g-drawer-close',
                '[class*="close"]',
                '[class*="drawer"] [class*="close"]',
                'button[aria-label="Close"]'
            ]
            
            for selector in close_selectors:
                try:
                    close_btn = self.driver.find_element(By.CSS_SELECTOR, selector)
                    if close_btn and close_btn.is_displayed():
                        close_btn.click()
                        self._human_delay(1, 2)
                        return True
                except:
                    continue
            
            # 尝试按ESC键
            try:
                from selenium.webdriver.common.keys import Keys
                self.driver.find_element(By.TAG_NAME, 'body').send_keys(Keys.ESCAPE)
                self._human_delay(1, 2)
                return True
            except:
                pass
            
            # 点击遮罩层
            try:
                mask = self.driver.find_element(By.CSS_SELECTOR, '.ecom-g-drawer-mask')
                if mask:
                    mask.click()
                    self._human_delay(1, 2)
                    return True
            except:
                pass
            
            return False
            
        except Exception as e:
            self.logger.error(f"关闭商品详情页失败: {e}")
            return False
    
    def convert_to_api_format(self, product: Dict[str, Any]) -> Dict[str, Any]:
        """转换为API格式"""
        try:
            # 构建产品数据字符串
            product_data_parts = []
            
            # 基础信息
            if product.get('product_id') and product['product_id'] != '未知':
                product_data_parts.append(f"商品编号: {product['product_id']}")
            
            if product.get('status') and product['status'] != '未知':
                product_data_parts.append(f"状态: {product['status']}")
            
            # 价格信息
            price = product.get('detail_price') or product.get('price', '未知')
            if price != '未知':
                product_data_parts.append(f"价格: {price}")
            
            # 库存和销量
            if product.get('stock') and product['stock'] != '未知':
                product_data_parts.append(f"库存: {product['stock']}")
            
            if product.get('sales') and product['sales'] != '未知':
                product_data_parts.append(f"销量: {product['sales']}")
            
            # 保障信息
            if product.get('safety_info'):
                product_data_parts.append(f"保障: {product['safety_info']}")
            
            # 物流信息
            if product.get('logistics_info'):
                product_data_parts.append(f"物流: {product['logistics_info']}")
            
            # 产品参数
            if product.get('product_params'):
                params_str = '; '.join([f"{k}: {v}" for k, v in product['product_params'].items()])
                product_data_parts.append(f"参数信息: {params_str}")
            
            # 店铺信息
            if product.get('shop_name'):
                product_data_parts.append(f"店铺: {product['shop_name']}")
            
            if product.get('shop_score'):
                product_data_parts.append(f"店铺评分: {product['shop_score']}")
            
            # 处理类目数据 - 按照用户需求的规则处理
            raw_category = product.get('category', '')
            processed_product_type = "抖音商品"  # 默认值
            
            if raw_category:
                raw_category = raw_category.strip()
                
                # 规则1: 存在 > 符号，取 > 后面的部分
                if '>' in raw_category:
                    parts = raw_category.split('>')
                    if len(parts) >= 2:
                        processed_product_type = parts[-1].strip()  # 取最后一个部分（> 后面的内容）
                        self.logger.info(f"📂 类目处理（规则1-取>后）: '{raw_category}' → '{processed_product_type}'")
                
                # 规则2: 不存在 > 但存在 / 符号，取第一个部分
                elif '/' in raw_category:
                    parts = raw_category.split('/')
                    if len(parts) >= 2:
                        processed_product_type = parts[0].strip()  # 取第一个部分（第一个/前面的内容）
                        self.logger.info(f"📂 类目处理（规则2-取/前）: '{raw_category}' → '{processed_product_type}'")
                
                # 规则3: 没有分隔符，保持原样
                else:
                    processed_product_type = raw_category
                    self.logger.info(f"📂 类目处理（规则3-保持原样）: '{processed_product_type}'")
            else:
                self.logger.info("⚠️ 使用默认值作为product_type（未找到商品类目）: 抖音商品")
            
            # 构建API格式
            api_format = {
                "home_image": product.get('product_image', ''),  # 使用提取到的商品图片
                "product_name": product.get('detail_title') or product.get('title', ''),
                "product_type": processed_product_type,  # 使用处理后的类目
                "product_data": '; '.join(product_data_parts) if product_data_parts else "暂无详细信息",
                "product_url": product.get('product_url', 'https://fxg.jinritemai.com/ffa/g/list'), # iframe详情页面URL
                "platform_product_id": product.get('product_id', '')
            }
            
            return api_format
            
        except Exception as e:
            self.logger.error(f"API格式转换失败: {e}")
            
            # 异常情况下也处理类目数据
            raw_category = product.get('category', '')
            processed_product_type = "抖音商品"  # 默认值
            
            if raw_category:
                raw_category = raw_category.strip()
                
                # 规则1: 存在 > 符号，取 > 后面的部分
                if '>' in raw_category:
                    parts = raw_category.split('>')
                    if len(parts) >= 2:
                        processed_product_type = parts[-1].strip()
                
                # 规则2: 不存在 > 但存在 / 符号，取第一个部分
                elif '/' in raw_category:
                    parts = raw_category.split('/')
                    if len(parts) >= 2:
                        processed_product_type = parts[0].strip()
                
                # 规则3: 没有分隔符，保持原样
                else:
                    processed_product_type = raw_category
            
            return {
                "home_image": "",
                "product_name": product.get('title', '未知商品'),
                "product_type": processed_product_type,  # 使用处理后的类目
                "product_data": "数据转换失败",
                "product_url": product.get('product_url', 'https://fxg.jinritemai.com/ffa/g/list'),
                "platform_product_id": product.get('product_id', '')
            }
    
    def save_products_data(self, products: List[Dict[str, Any]], filename: str = None):
        """保存商品数据"""
        try:
            if not filename:
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                filename = f"dy_products_{timestamp}.json"
            
            filepath = os.path.join(DYConfig.OUTPUT_DIR, filename)
            
            with open(filepath, 'w', encoding='utf-8') as f:
                json.dump(products, f, ensure_ascii=False, indent=2)
            
            print(f"💾 商品数据已保存: {filepath}")
            self.logger.info(f"保存商品数据: {len(products)} 个商品 -> {filepath}")
            
        except Exception as e:
            self.logger.error(f"保存数据失败: {e}")
    
    def submit_to_api(self, products: List[Dict[str, Any]], store_id: str) -> bool:
        """提交数据到API"""
        try:
            api_url = DYConfig.API_CONFIG['base_url'] + DYConfig.API_CONFIG['endpoints']['products']
            
            # 打印原始提取的商品数据
            print("\n" + "="*80)
            print("📦 原始提取的商品数据:")
            print("="*80)
            for i, product in enumerate(products, 1):
                print(f"\n🔍 原始商品 {i} 数据:")
                for key, value in product.items():
                    if key == 'element':
                        continue  # 跳过WebElement对象
                    if isinstance(value, str) and len(value) > 100:
                        print(f"  {key}: {value[:100]}...")
                    else:
                        print(f"  {key}: {value}")
            print("="*80)
            
            # 直接使用传入的API格式数据（GUI监听器已经转换过了）
            api_products = products
            
            # 构建请求数据
            payload = {
                "store_id": store_id,
                "platform": "抖音",
                "products": api_products
            }
            
            # 打印详细的API数据到控制台
            print("\n" + "="*80)
            print("🚀 准备提交到API的数据详情:")
            print("="*80)
            print(f"📋 Store ID: {store_id}")
            print(f"🏪 Platform: 抖音")
            print(f"📦 商品数量: {len(api_products)}")
            print("-"*80)
            
            for i, product in enumerate(api_products, 1):
                print(f"\n📦 商品 {i}:")
                print(f"  🏷️  商品名称: {product.get('product_name', 'N/A')}")
                print(f"  🆔 商品ID: {product.get('platform_product_id', 'N/A')}")
                # 从product_data字符串中提取价格
                product_data_str = product.get('product_data', '')
                price = 'N/A'
                if isinstance(product_data_str, str) and '价格:' in product_data_str:
                    try:
                        # 从字符串中提取价格信息
                        import re
                        price_match = re.search(r'价格:\s*([^;]+)', product_data_str)
                        if price_match:
                            price = price_match.group(1).strip()
                    except:
                        pass
                print(f"  💰 价格: {price}")
                print(f"  🖼️  封面图: {product.get('home_image', 'N/A')[:80]}{'...' if len(str(product.get('home_image', ''))) > 80 else ''}")
                print(f"  🔗 商品链接: {product.get('product_url', 'N/A')}")
                
                # 打印详细的product_data
                product_data = product.get('product_data', {})
                if isinstance(product_data, dict) and product_data:
                    print(f"  📊 详细数据:")
                    for key, value in product_data.items():
                        if key != '价格':  # 价格已经单独显示了
                            print(f"    • {key}: {value}")
                elif isinstance(product_data, str) and product_data:
                    print(f"  📊 详细数据: {product_data}")
                else:
                    print(f"  ⚠️  详细数据: 无")
            
            print("="*80)
            print("🔄 开始提交到API...")
            print("="*80)

            print(f"👌👌👌👌--最终的payload数据: {payload}")


            # 发送请求
            response = requests.post(
                api_url,
                json=payload,
                timeout=DYConfig.API_CONFIG['timeout']
            )
            
            if response.status_code == 200:
                print(f"✅ API提交成功: {len(api_products)} 个商品")
                self.logger.info(f"API提交成功: store_id={store_id}, 商品数={len(api_products)}")
                return True
            else:
                print(f"❌ API提交失败: {response.status_code} - {response.text}")
                self.logger.error(f"API提交失败: {response.status_code} - {response.text}")
                return False
                
        except Exception as e:
            self.logger.error(f"API提交异常: {e}")
            return False
    
    def _quick_verification_check(self) -> bool:
        """精准验证码检测 - iframe页面核心文字匹配（增强调试版）"""
        try:
            # 最快的方法：直接检查页面源码中是否包含验证码关键文字
            page_source = self.driver.page_source
            print(f"🔍 iframe页面源码长度: {len(page_source)} 字符")
            
            # 检查是否有异常的页面内容（可能被验证码阻挡）
            if len(page_source) < 50000:  # 正常详情页应该更长
                print(f"⚠️ 页面内容较少，可能存在验证码阻挡")
                print(f"🔍 页面源码片段（前200字符）: {page_source[:200]}")
                print(f"🔍 页面源码片段（后200字符）: {page_source[-200:]}")
            
            # 只检查最核心的验证码文字（避免误判）
            verification_keywords = [
                '请完成下列验证后继续',
                '按住左边按钮拖动完成上方拼图',
                # 增加一些可能的变体
                '请完成验证后继续',
                '完成验证后继续',
                '滑动验证',
                '验证码',
                'captcha'
            ]
            
            found_keywords = []
            for keyword in verification_keywords:
                if keyword in page_source:
                    found_keywords.append(keyword)
                    print(f"⚡ iframe检测到验证码关键字: {keyword}")
            
            # 额外检查：如果页面内容异常且包含特定标识
            suspicious_content = [
                'verification', 'verify', 'captcha', '验证', '滑动',
                'block', 'error', '错误', '异常'
            ]
            
            suspicious_found = []
            for content in suspicious_content:
                if content in page_source.lower():
                    suspicious_found.append(content)
            
            if suspicious_found and len(page_source) < 50000:
                print(f"⚠️ 发现可疑内容: {suspicious_found[:3]}")  # 只显示前3个
            
            if found_keywords:
                print(f"🔴 iframe检测结果: 发现 {len(found_keywords)} 个验证码关键字")
                return True
            else:
                print(f"🟢 iframe检测结果: 未发现验证码关键字")
                return False
            
        except Exception as e:
            print(f"🔍 快速验证码检测异常: {e}")
            return False
    
    def _handle_verification_pause(self, product) -> bool:
        """处理验证码暂停"""
        try:
            current_url = self.driver.current_url
            page_title = self.driver.title
            product_name = product.get('title', '未知商品') if isinstance(product, dict) else str(product)
            
            print(f"\n{'='*60}")
            print(f"⚠️  验证码检测 - 需要手动处理")
            print(f"{'='*60}")
            print(f"📦 当前商品: {product_name}")
            print(f"📍 当前页面: {current_url}")
            print(f"📄 页面标题: {page_title}")
            print(f"{'-'*60}")
            print(f"🔧 请在浏览器中手动处理:")
            print(f"   1. 完成滑动验证码")
            print(f"   2. 完成点击验证码")
            print(f"   3. 完成图形验证码")
            print(f"   4. 等待页面正常加载")
            print(f"{'-'*60}")
            print(f"💡 处理完成后选择:")
            print(f"   c/C - 继续获取当前商品详情")
            print(f"   s/S - 跳过当前商品")
            print(f"   q/Q - 退出整个程序")
            print(f"{'='*60}")
            
            # 使用GUI回调或命令行交互
            if hasattr(self, 'verification_callback') and self.verification_callback:
                # 使用GUI回调
                action = self.verification_callback("抖音", "iframe详情页")
                if action == 'continue':
                    print("✅ 继续获取商品详情...")
                    return True
                elif action == 'skip':
                    print("⏸️ 跳过当前商品")
                    return False
                elif action == 'quit':
                    print("🚪 退出程序")
                    sys.exit(0)
                else:
                    print("❌ 用户取消操作")
                    return False
            else:
                # 命令行交互模式
                while True:
                    try:
                        choice = input("请选择操作 (c=继续/s=跳过/q=退出): ").strip().lower()
                        
                        if choice in ['c', 'continue']:
                            print("✅ 继续获取商品详情...")
                            return True
                        elif choice in ['s', 'skip']:
                            print("⏸️ 跳过当前商品")
                            return False
                        elif choice in ['q', 'quit']:
                            print("🚪 退出程序")
                            sys.exit(0)
                        else:
                            print("❌ 无效选择，请输入 c(继续)/s(跳过)/q(退出)")
                            
                    except KeyboardInterrupt:
                        print("\n🚪 用户中断，退出程序")
                        sys.exit(0)
                    except Exception as e:
                        print(f"❌ 输入处理错误: {e}")
                    
        except Exception as e:
            self.logger.error(f"验证码处理失败: {e}")
            return False

    def __enter__(self):
        """上下文管理器入口"""
        if self._init_driver():
            return self
        else:
            raise Exception("浏览器初始化失败")
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器出口"""
        if self.driver:
            try:
                self.driver.quit()
                self.logger.info("浏览器已关闭")
            except Exception as e:
                self.logger.warning(f"关闭浏览器时出错: {e}")

    def get_product_list_with_categories(self, max_products_per_page: int = None) -> List[Dict[str, Any]]:
        """获取商品列表并提取类目信息（优化版本）"""
        try:
            # 第一步：快速获取所有商品基础信息
            print("📦 第一步：快速获取商品基础信息...")
            products = self.get_product_list(max_products_per_page)  # 使用现有方法
            
            if not products:
                print("❌ 未获取到商品基础信息")
                return products
            
            print(f"✅ 成功获取 {len(products)} 个商品的基础信息")
            
            # 第二步：批量提取类目信息
            print(f"🔍 第二步：开始批量提取 {len(products)} 个商品的类目信息...")
            products_with_categories = self._extract_categories_for_products(products)
            
            print(f"🎉 完成！共处理 {len(products_with_categories)} 个商品")
            return products_with_categories
            
        except Exception as e:
            self.logger.error(f"获取商品列表和类目失败: {e}")
            print(f"❌ 获取商品列表和类目失败: {e}")
            return []
    
    def _extract_categories_for_products(self, products: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """批量提取商品类目信息"""
        try:
            print("🔍 开始批量类目提取...")
            
            # 确保在商品列表页面
            current_url = self.driver.current_url
            if 'ffa/g/list' not in current_url:
                print("⚠️ 当前不在商品列表页面，可能影响类目提取")
            
            # 为每个商品提取类目
            for i, product in enumerate(products):
                try:
                    print(f"\n🔍 提取第 {i+1}/{len(products)} 个商品的类目...")
                    print(f"   商品名称: {product.get('title', '未知')[:30]}...")
                    
                    # 提取类目信息
                    category = self._extract_category_by_index(i)
                    
                    if category:
                        product['category'] = category
                        print(f"✅ 类目提取成功: {category}")
                    else:
                        product['category'] = ""
                        print("⚠️ 类目提取失败，使用空值")
                    
                    # 商品间延迟，避免操作过快
                    if i < len(products) - 1:  # 最后一个商品不需要延迟
                        self._human_delay(0.5, 1)
                        
                except Exception as e:
                    product['category'] = ""
                    print(f"❌ 第 {i+1} 个商品类目提取异常: {e}")
                    self.logger.error(f"商品类目提取异常: {e}")
            
            # 统计提取结果
            success_count = len([p for p in products if p.get('category')])
            print(f"\n📊 类目提取完成统计:")
            print(f"   ✅ 成功提取: {success_count} 个")
            print(f"   ❌ 提取失败: {len(products) - success_count} 个")
            
            return products
            
        except Exception as e:
            self.logger.error(f"批量类目提取失败: {e}")
            print(f"❌ 批量类目提取失败: {e}")
            # 确保所有商品都有category字段
            for product in products:
                if 'category' not in product:
                    product['category'] = ""
            return products
    
    def _extract_category_by_index(self, product_index: int) -> str:
        """根据商品索引提取类目信息（优化版本）"""
        try:
            # 查找页面上所有的编辑按钮
            edit_buttons = self._find_all_edit_buttons()
            
            if not edit_buttons:
                print("❌ 未找到任何编辑按钮")
                return ""
            
            if product_index >= len(edit_buttons):
                print(f"⚠️ 商品索引 {product_index} 超出编辑按钮数量 {len(edit_buttons)}")
                # 使用最后一个可用的编辑按钮
                product_index = len(edit_buttons) - 1
            
            # 使用对应的编辑按钮
            edit_button = edit_buttons[product_index]
            
            # 提取类目
            category = self._extract_category_from_edit_button(edit_button, product_index)
            
            return category
            
        except Exception as e:
            self.logger.error(f"根据索引提取类目失败: {e}")
            print(f"❌ 索引 {product_index} 类目提取异常: {e}")
            return ""
    
    def _find_all_edit_buttons(self) -> List:
        """查找页面上所有的编辑按钮"""
        try:
            edit_buttons = []
            
            # 更精确的选择器策略 - 避免点击到"编辑记录"
            selectors = [
                "//*[@data-btm='d63429' and contains(text(), '编辑')]",  # 精确匹配真正的编辑按钮
                "//span[@data-btm='d63429'][contains(text(), '编辑')]", # 更具体的span选择器
                "//span[text()='编辑' and @data-btm='d63429']",        # 完全匹配文本和属性
            ]
            
            for selector in selectors:
                try:
                    elements = self.driver.find_elements(By.XPATH, selector)
                    if elements:
                        edit_buttons = elements
                        print(f"✅ 使用精确选择器找到 {len(elements)} 个真正的编辑按钮")
                        break
                except Exception as e:
                    self.logger.debug(f"选择器 '{selector}' 失败: {e}")
            
            # 如果精确选择器没找到，使用备用策略（但要过滤掉编辑记录）
            if not edit_buttons:
                print("⚠️ 精确选择器未找到，尝试备用策略...")
                try:
                    # 查找所有包含"编辑"文本的元素
                    all_edit_elements = self.driver.find_elements(By.XPATH, "//span[contains(text(), '编辑')]")
                    
                    # 过滤掉"编辑记录"按钮
                    for element in all_edit_elements:
                        try:
                            text = element.text.strip()
                            # 只要纯"编辑"文本，排除"编辑记录"
                            if text == "编辑":
                                # 进一步检查是否有data-btm属性（真正的编辑按钮特征）
                                data_btm = element.get_attribute("data-btm")
                                if data_btm:  # 有data-btm属性的是真正的编辑按钮
                                    edit_buttons.append(element)
                        except Exception as e:
                            self.logger.debug(f"过滤元素时出错: {e}")
                    
                    if edit_buttons:
                        print(f"✅ 备用策略找到 {len(edit_buttons)} 个编辑按钮")
                    
                except Exception as e:
                    self.logger.debug(f"备用策略失败: {e}")
            
            # 进一步过滤可见的编辑按钮
            visible_buttons = []
            for button in edit_buttons:
                try:
                    if button.is_displayed() and button.is_enabled():
                        # 再次验证不是编辑记录按钮
                        parent_element = button.find_element(By.XPATH, "..")
                        parent_html = parent_element.get_attribute("outerHTML")
                        
                        # 如果父元素包含"编辑记录"相关的属性，则跳过
                        if "商品编辑记录" not in parent_html and "编辑记录" not in parent_html:
                            visible_buttons.append(button)
                        else:
                            print(f"⚠️ 跳过编辑记录按钮")
                except Exception as e:
                    self.logger.debug(f"验证按钮可见性时出错: {e}")
            
            print(f"📋 最终找到 {len(visible_buttons)} 个可用的真正编辑按钮")
            
            # 调试信息：显示找到的按钮详情
            for i, button in enumerate(visible_buttons):
                try:
                    text = button.text.strip()
                    data_btm = button.get_attribute("data-btm")
                    print(f"   按钮 {i+1}: 文本='{text}', data-btm='{data_btm}'")
                except:
                    pass
            
            return visible_buttons
            
        except Exception as e:
            self.logger.error(f"查找编辑按钮失败: {e}")
            return []
    
    def _extract_category_from_edit_button(self, edit_button, button_index: int) -> str:
        """从编辑按钮提取类目信息（优化版本）"""
        try:
            # 记录当前窗口状态
            original_window = self.driver.current_window_handle
            original_windows = set(self.driver.window_handles)
            
            # 滚动到编辑按钮可见位置
            self.driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", edit_button)
            self._human_delay(1, 2)
            
            # 点击编辑按钮
            print(f"🖱️ 点击第 {button_index+1} 个编辑按钮...")
            self.driver.execute_script("arguments[0].click();", edit_button)
            
            # 等待新窗口打开
            new_window = self._wait_for_new_window(original_windows, timeout=8)
            if not new_window:
                print("❌ 新窗口未在预期时间内打开")
                return ""
            
            # 切换到新窗口并提取类目
            self.driver.switch_to.window(new_window)
            print("🔄 已切换到编辑页面")
            
            # 等待页面加载
            self._human_delay(2, 4)
            
            # 提取类目信息
            category = self._extract_category_from_edit_page()
            
            # 清理：关闭新窗口并回到原窗口
            try:
                self.driver.close()
                self.driver.switch_to.window(original_window)
                print("🔄 已回到商品列表页面")
                self._human_delay(0.5, 1)
            except Exception as e:
                print(f"⚠️ 窗口切换时出错: {e}")
                # 确保回到原窗口
                try:
                    self.driver.switch_to.window(original_window)
                except:
                    pass
            
            return category
            
        except Exception as e:
            self.logger.error(f"从编辑按钮提取类目失败: {e}")
            print(f"❌ 编辑按钮 {button_index+1} 类目提取异常: {e}")
            
            # 确保回到原窗口
            try:
                if len(self.driver.window_handles) > 1:
                    self.driver.close()
                    self.driver.switch_to.window(self.driver.window_handles[0])
            except:
                pass
            
            return ""
    
    def _wait_for_new_window(self, original_windows: set, timeout: int = 8) -> str:
        """等待新窗口打开"""
        for i in range(timeout):
            try:
                current_windows = set(self.driver.window_handles)
                new_windows = current_windows - original_windows
                
                if new_windows:
                    new_window = list(new_windows)[0]
                    print("✅ 新窗口已打开")
                    return new_window
                
                time.sleep(1)
            except Exception as e:
                self.logger.debug(f"等待新窗口时出错: {e}")
                time.sleep(1)
        
        return ""
    
    def _extract_category_from_edit_page(self) -> str:
        """从编辑页面提取类目信息"""
        try:
            category = ""
            
            # 首先验证是否在正确的编辑页面
            print("🔍 验证编辑页面...")
            try:
                # 检查页面URL
                current_url = self.driver.current_url
                print(f"   当前页面URL: {current_url}")
                
                # 检查页面标题
                page_title = self.driver.title
                print(f"   页面标题: {page_title}")
                
                # 检查是否包含编辑页面的关键元素
                key_elements = [
                    "基础信息",
                    "商品类目", 
                    "商品标题"
                ]
                
                page_text = self.driver.find_element(By.TAG_NAME, "body").text
                found_elements = [elem for elem in key_elements if elem in page_text]
                print(f"   找到关键元素: {found_elements}")
                
                if len(found_elements) < 2:
                    print("⚠️ 可能不在正确的编辑页面，但继续尝试提取...")
                else:
                    print("✅ 确认在商品编辑页面")
                    
            except Exception as e:
                print(f"⚠️ 页面验证时出错: {e}")
            
            # 主要选择器策略
            primary_selectors = [
                '.style_currentCategory__Dnq9o',      # 从HTML结构中看到的精确类名
                'div[class*="currentCategory"]',       # 包含currentCategory的类
                'div[class*="category"]'               # 包含category的类
            ]
            
            # 尝试精确匹配
            for selector in primary_selectors:
                try:
                    elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    if elements:
                        category_text = elements[0].text.strip()
                        if category_text and ('>' in category_text or '/' in category_text):
                            category = category_text
                            print(f"✅ 精确匹配找到类目: {category}")
                            return category
                except Exception as e:
                    self.logger.debug(f"精确选择器 '{selector}' 失败: {e}")
            
            # 广泛搜索策略
            if not category:
                print("🔍 使用广泛搜索策略...")
                try:
                    # 查找包含层级分隔符的文本
                    xpath_patterns = [
                        "//div[contains(text(), '>') and contains(text(), '/')]",  # 同时包含两种分隔符
                        "//div[contains(text(), '>')]",                           # 包含 > 分隔符
                        "//div[contains(text(), '/') and string-length(text()) > 5]",  # 包含 / 且长度大于5
                        "//span[contains(text(), '>')]",                          # span标签中的类目
                    ]
                    
                    for xpath in xpath_patterns:
                        try:
                            elements = self.driver.find_elements(By.XPATH, xpath)
                            for element in elements:
                                text = element.text.strip()
                                # 验证是否为有效的类目格式
                                if self._is_valid_category_text(text):
                                    category = text
                                    print(f"✅ 广泛搜索找到类目: {category}")
                                    return category
                        except Exception as e:
                            self.logger.debug(f"广泛搜索XPath '{xpath}' 失败: {e}")
                            
                except Exception as e:
                    self.logger.debug(f"广泛搜索失败: {e}")
            
            # 如果还是没找到，尝试查找"商品类目"标签附近的内容
            if not category:
                print("🔍 尝试查找'商品类目'标签附近的内容...")
                try:
                    # 查找包含"商品类目"或"类目"的标签
                    category_labels = self.driver.find_elements(By.XPATH, "//*[contains(text(), '商品类目') or contains(text(), '类目')]")
                    
                    for label in category_labels:
                        try:
                            # 查找同级或父级元素中的类目信息
                            parent = label.find_element(By.XPATH, "..")
                            siblings = parent.find_elements(By.XPATH, ".//*")
                            
                            for sibling in siblings:
                                text = sibling.text.strip()
                                if self._is_valid_category_text(text):
                                    category = text
                                    print(f"✅ 在类目标签附近找到: {category}")
                                    return category
                        except Exception as e:
                            self.logger.debug(f"查找类目标签附近内容时出错: {e}")
                            
                except Exception as e:
                    self.logger.debug(f"查找类目标签失败: {e}")
            
            if not category:
                print("⚠️ 未能在编辑页面找到类目信息")
                # 输出页面部分内容用于调试
                try:
                    body_text = self.driver.find_element(By.TAG_NAME, "body").text[:500]
                    print(f"📄 页面内容片段: {body_text}...")
                except:
                    pass
            
            return category
            
        except Exception as e:
            self.logger.error(f"从编辑页面提取类目失败: {e}")
            return ""
    
    def _is_valid_category_text(self, text: str) -> bool:
        """验证文本是否为有效的类目格式"""
        if not text or len(text) < 3:
            return False
        
        # 必须包含分隔符
        if not ('>' in text or '/' in text):
            return False
        
        # 排除无效关键词
        invalid_keywords = [
            'http', 'www', 'com', 'html', 'script', 'function', 'var', 'console',
            'undefined', 'null', 'true', 'false', 'return', 'class', 'style',
            '编辑记录', '商品编辑记录', 'data-', 'onclick', 'javascript'
        ]
        
        text_lower = text.lower()
        for keyword in invalid_keywords:
            if keyword in text_lower:
                return False
        
        # 必须包含中文字符（抖音的类目都是中文）
        import re
        if not re.search(r'[\u4e00-\u9fff]', text):
            return False
        
        # 长度限制
        if len(text) > 100:
            return False
        
        # 检查是否像是类目格式（包含常见的类目分隔符模式）
        category_patterns = [
            r'[\u4e00-\u9fff/]+\s*>\s*[\u4e00-\u9fff/]+',  # 中文 > 中文
            r'[\u4e00-\u9fff/]+\s*/\s*[\u4e00-\u9fff/]+',  # 中文/中文
        ]
        
        for pattern in category_patterns:
            if re.search(pattern, text):
                return True
        
        # 如果包含多个分隔符，可能是多级类目
        separator_count = text.count('>') + text.count('/')
        if separator_count >= 1:
            # 检查分隔符前后是否都有中文内容
            parts = re.split(r'[>/]', text)
            chinese_parts = [part.strip() for part in parts if part.strip() and re.search(r'[\u4e00-\u9fff]', part.strip())]
            
            if len(chinese_parts) >= 2:  # 至少两个中文部分
                return True
        
        return False
    
    def _extract_product_id_from_href(self, href: str) -> str:
        """从href属性中提取商品ID"""
        try:
            # 查找包含href的链接元素
            link_element = self.driver.find_element(By.TAG_NAME, 'a')
            href = link_element.get_attribute('href')
            if href:
                # 从URL中提取ID
                import re
                id_match = re.search(r'id[=:](\d+)', href)
                if id_match:
                    return id_match.group(1)
        except:
            pass
        return ""

# 测试代码
if __name__ == "__main__":
    print("🎯 DY抖音电商爬虫完整测试")
    print("=" * 60)
    print("📋 功能特性:")
    print("   ✅ 配置系统完整")
    print("   ✅ 双模式登录支持 (交互式/手动)")
    print("   ✅ 反检测机制")
    print("   ✅ 商品列表获取")
    print("   ✅ iframe详情数据获取")
    print("   ✅ API格式转换")
    print("=" * 60)
    
    # 配置验证
    if not DYConfig.validate_config():
        print("❌ 配置验证失败，请检查")
        sys.exit(1)
    
    # 完整功能测试
    try:
        with DYScraper(headless=False, debug=True) as scraper:
            print("\n✅ 爬虫初始化成功")
            
            # 自动化测试，默认选择y
            user_input = 'y'  # 自动化测试
            
            # 测试登录功能
            print(f"\n🤔 是否测试登录功能？(y/n): {user_input}")
            if user_input == 'y':
                if scraper.login_dy():
                    print("🎉 登录测试成功！")
                    
                    # 导航到商品管理页面
                    shop_url = "https://fxg.jinritemai.com/ffa/g/list"
                    if scraper.navigate_to_shop(shop_url):
                        print("✅ 成功导航到商品管理页面")
                        
                        # 获取商品列表
                        print(f"\n🤔 是否获取商品列表？(y/n): {user_input}")
                        if user_input == 'y':
                            products = scraper.get_product_list(max_products_per_page=5)
                            
                            if products:
                                print(f"✅ 成功获取 {len(products)} 个商品")
                                
                                # 获取商品详情
                                print(f"\n🤔 是否获取商品详情？(y/n): {user_input}")
                                if user_input == 'y':
                                    detailed_products = scraper.get_product_details(products, max_products=2)
                                    
                                    if detailed_products:
                                        print(f"✅ 成功获取 {len(detailed_products)} 个商品详情")
                                        
                                        # 转换为API格式
                                        api_products = []
                                        for product in detailed_products:
                                            # 移除WebElement对象避免序列化错误
                                            clean_product = {k: v for k, v in product.items() if k != 'element'}
                                            api_product = scraper.convert_to_api_format(clean_product)
                                            api_products.append(api_product)
                                        
                                        # 保存数据
                                        scraper.save_products_data(api_products, "dy_products_test.json")
                                        print("💾 测试数据已保存到 dy_products_test.json")
                                        
                                        # 显示示例数据
                                        print("\n📋 API格式示例:")
                                        print(json.dumps(api_products[0], ensure_ascii=False, indent=2))
                                    else:
                                        print("❌ 商品详情获取失败")
                                else:
                                    print("⏸️  跳过商品详情获取")
                            else:
                                print("❌ 商品列表获取失败")
                        else:
                            print("⏸️  跳过商品列表获取")
                    else:
                        print("❌ 导航到商品管理页面失败")
                else:
                    print("❌ 登录测试失败")
            else:
                print("⏸️  跳过登录测试")
            
            print("\n🎉 完整测试完成")
            
    except Exception as e:
        print(f"❌ 测试失败: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1) 